/// Sync[T] represents an effect that returns a T value synchronously.
/// It is a subtype of Async[T]. Different from general Async, an Sync
/// is guaranteed synchronous and cannot be cancelled half-way.
/// There is a `sync` function, which can be used to concatenate
/// multiple Sync effects into a single Sync effect.
type Sync [out T = unit]
    protected
    Async[T];

/// Async[T,E] represents an effect that may return a T value,
/// or throw an E error, synchronously or asynchronously.
/// It is a subtype of Observable[T,E] and can be regarded as a lazy Promise.
type Async [out T = unit, out E = never]
    protected
    Observable[T,E];


export function with: [O < Observable[any,any]]
    &(O, Async) => O
    native '__With';

export function do: [A, K < Observable[any,any]]
    &(Sync[A], &(A) => K) => K
    native '__Do';

/// await(a1, r1 => a2) returns an action that performs a1 first and then
///   transforms r1 (the result of a1) into a2 and performs a2.
export function await:[A,B,E]
    &(Async[A,E], &(A) => Async[B,E]) => Async[B,E]
    native '__Await';


export function map:[A,B,E]
    &(Async[A,E], &(A) => B) => Async[B,E]
    native '__ObservableMap';

export function map-to:[A,B,E]
    &(Async[A,E], B) => Async[B,E]
    &(e,v) => e.{map(&(_) => v)};

export function merge:
    &(List[Async[never]]) => Async[never]
    native '__ObservableMerge';


